package com.bfly.mall.wechat.service.impl;

import com.bfly.core.base.service.BaseServiceImpl;
import com.bfly.core.config.ResourceConfigure;
import com.bfly.core.enums.SysError;
import com.bfly.core.exception.ServiceResponseException;
import com.bfly.mall.wechat.common.WeChatAPi;
import com.bfly.mall.wechat.dao.WeChatMpMaterialMapper;
import com.bfly.mall.wechat.dto.WeChatMpMaterialFormDTO;
import com.bfly.mall.wechat.entity.WeChatMp;
import com.bfly.mall.wechat.entity.WeChatMpMaterial;
import com.bfly.mall.wechat.enums.WeChatMpMaterialEnum;
import com.bfly.mall.wechat.mp.dto.*;
import com.bfly.mall.wechat.mp.service.WeChatMPAPi;
import com.bfly.mall.wechat.service.IWeChatMpMaterialService;
import com.bfly.mall.wechat.service.IWeChatMpService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 长沙商脉科技有限公司
 * @date 2021/1/4 14:31
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS)
public class WeChatMpMaterialServiceImpl extends BaseServiceImpl<WeChatMpMaterial, Integer> implements IWeChatMpMaterialService {

    @Autowired
    private WeChatMpMaterialMapper weChatMpMaterialMapper;
    @Autowired
    private IWeChatMpService weChatMpService;

    @Override
    public WeChatMpMaterial getMaterial(int platformId, String mediaId) {
        WeChatMpMaterial material = weChatMpMaterialMapper.getMaterial(platformId, mediaId);
        return material;
    }

    @Override
    public List<WeChatMpMaterial> getNewsMaterial(int platformId, String mediaId) {
        return weChatMpMaterialMapper.getNewsMaterial(platformId, mediaId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(WeChatMpMaterialFormDTO... formDTOs) {
        // 图文
        List<WeChatMpMaterialFormDTO> newsList = Arrays.stream(formDTOs).filter(formDTO -> formDTO.getType().equalsIgnoreCase(WeChatMpMaterialEnum.NEWS.getType())).collect(Collectors.toList());
        saveNewsMaterial(newsList);

        // 非图文
        List<WeChatMpMaterialFormDTO> normalList = Arrays.stream(formDTOs).filter(formDTO -> !formDTO.getType().equalsIgnoreCase(WeChatMpMaterialEnum.NEWS.getType())).collect(Collectors.toList());
        saveNormalMaterial(normalList);
    }

    /**
     * 上传非图文的素材
     *
     * @author 长沙商脉科技有限公司
     * @date 2021/1/11 18:59
     */
    private void saveNormalMaterial(List<WeChatMpMaterialFormDTO> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (WeChatMpMaterialFormDTO formDTO : list) {
            WeChatMpMaterialEnum materialEnum = WeChatMpMaterialEnum.getMaterialType(formDTO.getType());
            if (materialEnum == null) {
                throw new ServiceResponseException(SysError.PARAM_ERROR, "素材类型错误!");
            }
            WeChatMp weChatMp = weChatMpService.get(formDTO.getPlatformId());
            if (weChatMp == null) {
                throw new ServiceResponseException(SysError.PARAM_ERROR, "不存在的平台类型!");
            }
            String file = formDTO.getFile();
            WeChatMpAddForeverMaterialRequest materialRequest = new WeChatMpAddForeverMaterialRequest();
            try {
                switch (materialEnum) {
                    case IMAGE:
                        Assert.hasLength(file, "图片素材不能为空!");
                        Assert.hasLength(formDTO.getFileName(), "图片素材名称不能为空!");
                        break;
                    case VOICE:
                        Assert.hasLength(file, "语音素材不能为空!");
                        Assert.hasLength(formDTO.getFileName(), "语音素材名称不能为空!");
                        break;
                    case VIDEO:
                        Assert.hasLength(file, "视频素材不能为空!");
                        Assert.hasLength(formDTO.getFileName(), "视频素材名称不能为空!");
                        Assert.hasLength(formDTO.getTitle(), "视频素材标题不能为空!");
                        Assert.hasLength(formDTO.getDigest(), "视频素材描述不能为空!");
                        break;
                }
                materialRequest.setType(materialEnum.getType());
                materialRequest.setFileName(formDTO.getFileName());
                materialRequest.setTitle(formDTO.getTitle());
                materialRequest.setRemark(formDTO.getDigest());
                materialRequest.setFile(file);
            } catch (Exception e) {
                throw new ServiceResponseException(SysError.ERROR, e.getMessage());
            }

            WeChatMpMaterial material = new WeChatMpMaterial();
            BeanUtils.copyProperties(formDTO, material);
            material.setSeq(0);
            material.setCreateDate(new Date());
            super.save(material);

            WeChatMpAddForeverMaterialResponse materialResponse = null;
            File f = new File(ResourceConfigure.getResourceAbsolutePath(file));
            if (!f.exists()) {
                throw new ServiceResponseException(SysError.PARAM_ERROR, "上传的文件不存在!");
            }
            materialRequest.setFile(f.getPath());
            materialResponse = WeChatMPAPi.addForeverMaterial(weChatMp.getAppId(), weChatMp.getAppSecret(), materialRequest);
            // 回写media_id 图片回写地址
            material.setMediaId(materialResponse.getMedia_id());
            material.setCover(materialResponse.getUrl());
            if(materialEnum==WeChatMpMaterialEnum.VIDEO){
                // 回写视频下载地址
                WeChatMpForeverMaterialInfoResponse materialInfoResponse = WeChatMPAPi.getForeverMaterial(weChatMp.getAppId(), weChatMp.getAppSecret(), materialResponse.getMedia_id());
                material.setLink(materialInfoResponse.getDown_url());
            }
            super.edit(material);
        }
    }

    /**
     * 上传图文素材
     *
     * @author 长沙商脉科技有限公司
     * @date 2021/1/11 18:59
     */
    private void saveNewsMaterial(List<WeChatMpMaterialFormDTO> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        Collections.sort(list);
        List<WeChatMpMaterial> materials = new ArrayList<>();
        WeChatMp weChatMp = weChatMpService.get(list.get(0).getPlatformId());
        WeChatMpAddForeverNewsMaterialRequest request = new WeChatMpAddForeverNewsMaterialRequest();
        for (int i = 0; i < list.size(); i++) {
            WeChatMpMaterialFormDTO formDTO = list.get(i);
            WeChatMpAddForeverMaterialRequest materialRequest = new WeChatMpAddForeverMaterialRequest();
            try {
                Assert.hasLength(formDTO.getFileName(), "图文封面素材ID不能为空!");
                Assert.hasLength(formDTO.getCover(), "图文封面素材不能为空!");
                Assert.hasLength(formDTO.getTitle(), "图文封面素材标题不能为空!");
                Assert.hasLength(formDTO.getContent(), "图文素材内容不能为空!");
                Assert.hasLength(formDTO.getDigest(), "图文素材描述不能为空!");

                materialRequest.setType(WeChatMpMaterialEnum.NEWS.getType());
                materialRequest.setTitle(formDTO.getTitle());
                materialRequest.setRemark(formDTO.getDigest());
            } catch (Exception e) {
                throw new ServiceResponseException(SysError.ERROR, e.getMessage());
            }

            WeChatMpMaterial material = new WeChatMpMaterial();
            BeanUtils.copyProperties(formDTO, material);
            material.setSeq(i);
            material.setCreateDate(new Date());
            material.setMore(list.size() > 1);
            super.save(material);
            materials.add(material);
            request.add(formDTO);
        }

        WeChatMpAddForeverMaterialResponse response = WeChatMPAPi.addForeverMaterial(weChatMp.getAppId(), weChatMp.getAppSecret(), request);
        WeChatMpForeverMaterialInfoResponse materialInfoResponse = WeChatMPAPi.getForeverMaterial(weChatMp.getAppId(), weChatMp.getAppSecret(), response.getMedia_id());
        List<WeChatMpForeverMaterialInfoResponse.News> newsItems = materialInfoResponse.getNews_item();
        WeChatMpMaterial material;
        String url;
        for (int i = 0; i < materials.size(); i++) {
            url = newsItems.get(i).getUrl();
            material = materials.get(i);
            // 回写图文访问地址
            material.setMediaId(response.getMedia_id());
            material.setLink(url);
            super.edit(material);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(WeChatMpMaterialFormDTO... formDTOs) {
        List<WeChatMpMaterialFormDTO> list = Arrays.asList(formDTOs);
        Collections.sort(list);

        List<WeChatMpMaterial> materials = new ArrayList<>();
        WeChatMp weChatMp = weChatMpService.get(list.get(0).getPlatformId());
        if (weChatMp == null) {
            throw new ServiceResponseException(SysError.PARAM_ERROR, "不存在的平台类型!");
        }
        for (int i = 0; i < formDTOs.length; i++) {
            WeChatMpMaterialFormDTO formDTO = formDTOs[i];
            try {
                Assert.hasLength(formDTO.getTitle(), "图文素材标题不能为空!");
                Assert.hasLength(formDTO.getContent(), "图文素材内容不能为空!");
                Assert.hasLength(formDTO.getDigest(), "图文素材描述不能为空!");
                Assert.hasLength(formDTO.getCover(), "图文素材封面不能为空!");
            } catch (Exception e) {
                throw new ServiceResponseException(SysError.ERROR, e.getMessage());
            }

            WeChatMpMaterial material = get(formDTO.getId());
            if (material == null) {
                throw new ServiceResponseException(SysError.PARAM_ERROR, "不存在的素材!");
            }
            WeChatMpMaterialEnum materialEnum = WeChatMpMaterialEnum.getMaterialType(material.getType());
            if (materialEnum != WeChatMpMaterialEnum.NEWS) {
                throw new ServiceResponseException(SysError.PARAM_ERROR, "素材类型错误,只支持图文类型的素材编辑!");
            }
            material.setSeq(i);
            material.setTitle(formDTO.getTitle());
            material.setCover(formDTO.getCover());
            material.setAuthor(formDTO.getAuthor());
            material.setSourceUrl(formDTO.getSourceUrl());
            material.setDigest(formDTO.getDigest());
            material.setContent(formDTO.getContent());
            material.setShowCover(formDTO.isShowCover());
            material.setUpdateDate(new Date());
            super.edit(material);

            materials.add(material);
            WeChatMpEditForeverNewsMaterialRequest request = new WeChatMpEditForeverNewsMaterialRequest(material.getMediaId(), material.getSeq());
            request.add(formDTO);
            WeChatMPAPi.editForeverMaterial(weChatMp.getAppId(), weChatMp.getAppSecret(), request);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(int platformId, String mediaId) {
        WeChatMp weChatMp = weChatMpService.get(platformId);
        if (weChatMp == null) {
            throw new ServiceResponseException(SysError.PARAM_ERROR, "不存在的平台类型!");
        }
        weChatMpMaterialMapper.delMaterial(platformId, mediaId);
        WeChatMPAPi.deleteForeverMaterial(weChatMp.getAppId(), weChatMp.getAppSecret(), mediaId);
        super.getCache().clear();
    }

    @Override
    public List<WeChatMpMaterial> getSubNews(String mediaId) {
        return weChatMpMaterialMapper.getSubNews(mediaId);
    }
}
